package cn.liujianbo.example.base.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * 反射动态修改 实例常量 和 类常量 的值
 * @author 刘建波
 * @date 2021-01-14 15:31
 */
public class UpdateFinalVariableDemo {
    public static final int classFinalVariable = 5;
    private final int instanceFinalVariable = 1;

    public int getInstanceFinalVariable() {
        return this.instanceFinalVariable;
    }

    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
        UpdateFinalVariableDemo instance = new UpdateFinalVariableDemo();
        Field[] fields = instance.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equals("a")) {
                // 修改实例常量 a 的值
                field.setAccessible(true);
                field.set(instance, 2);
                // 利用反射可以修改 final 常量
                System.out.println(field.get(instance));
                // 通过方法获得的还是1，是因为编译器优化，把 getA() return this.a; 优化成 return 1;
                System.out.println(instance.getInstanceFinalVariable());
            } else{
                /**
                 * 修改类常量 aa 的值
                 */
                field.setAccessible(true);
                // 获取字段 的 定义字段（描述Filed的Filed）
                Field modifiersField = Field.class.getDeclaredField("modifiers");
                modifiersField.setAccessible(true);
                // 修改类常量字段的定义  public 为 1   static 为 8  final 为 16
                // filed.getModifiers() 就是 25  去掉 final 定义
                modifiersField.set(field, field.getModifiers() & ~Modifier.FINAL);
                // 修改类常量的值
                field.set(null, 2);
                System.out.println(field.get(null));
            }
        }
    }
}
